package org.example.myfilter;

import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.http.HttpHeaders;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.List;
//不知道为什么要交给ioc管理?????
@Component
public class MyLoginFilter implements GlobalFilter {

    /*首先自定一个类实现GlobalFilter接口
    * 再重写Filter方法
    * exchange：请求相关的参数
    * chain 过滤器链
    * */

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {

        /*
          从前端获取请求
          从请求头中获取令牌
          解析令牌 如果失败 则返回错误
          如果成功就放行
        *
        * */
        //mutate().build() 相当于复制一个请求
        ServerHttpRequest request = exchange.getRequest().mutate().build();
        HttpHeaders headers = request.getHeaders();
        List<String> token = headers.get("token");
        if(token == null || token.isEmpty()){
            throw new RuntimeException();
        }else {
            //？？？

            /* 首先需求是需要把我们现在解析的令牌传给微服务
            如果不传的话 后续走到某一个微服务的时候还是需要解析 但我也不知道为什么不传的时候还要解析 是因为传过去还是token？
            所以我现在需要先把 解析后的令牌的 加到请求头上？
            再把请求头加到请求中




             网络中能带数据的技术  用户带数据到网关
            用户带数据是请求头带的
             可以让网关到某个服务时候再给他加个请求头
             用户到网关带的请求头是令牌
             那我网关到某个服务 加个请求头，然后带的请求头可以是令牌解析出来的内容
            * */

            /*  请求头中携带中文会乱码 是因为http协议默认用IS08859-1编码请求头的数据，中文会乱码
            ？？？没懂为什么这样二次请求了
            我知道了 是因为newRequest 时是把中文解析了 但是后面传到某个微服务时
            return chain.filter(newExchange); 返回的这个值传到 某个服务时 还是用的请求头

            * */
            ServerHttpRequest newRequest = exchange.getRequest()
                    .mutate().header("loginUser", token.get(0)).build();
            ServerWebExchange newExchange = exchange.mutate().request(newRequest).build();

            return chain.filter(newExchange);
        }
    }
}
/*
所以这里是先获取请求 然后复制 加了一个请求头
  创建新的请求 再获取请求 复制 再添加新的请求 再创建？
你的理解基本正确，但更准确地说，这段代码的逻辑是：

1. **获取原始请求对象**：`exchange.getRequest()` 获取当前交换（`ServerWebExchange`）中的原始请求（`ServerHttpRequest`）
2. **创建修改后的请求**：通过 `.mutate()` 方法创建请求的可变副本，添加 `loginUser` 头信息后，用 `.build()` 生成新的请求对象 `newRequest`
3. **创建新的交换对象**：基于原始交换对象 `exchange`，通过 `.mutate()` 创建交换的可变副本，将其请求替换为新创建的 `newRequest`，再通过 `.build()` 生成新的交换对象 `newExchange`

整个过程是**一次复制-修改-重建**的操作，而不是多次重复。这种方式符合 Spring WebFlux 中请求对象的不可变设计原则（原始请求对象通常不可直接修改，需要通过 `mutate()` 方法创建副本进行修改）。

简单来说，就是：基于原始请求创建带新头的请求 → 基于原始交换创建包含新请求的交换。这样就能在不修改原始对象的前提下，得到包含新请求头的交换对象。*/